//+------------------------------------------------------------------+
//|                                                 HashFunction.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| BitInterpreter 联合体：位序列解释器                               |
//| 核心作用：允许以不同数据类型“查看”同一段内存的位序列（内存共享），   |
//|           主要用于将浮点类型（float/double）的二进制表示转换为整数类型， |
//|           从而基于其位模式计算哈希值（避免浮点数值直接转换导致的精度问题） |
//| 适用场景：浮点类型哈希计算（将 float/double 的位模式解析为 int/long 进行处理） |
//+------------------------------------------------------------------+
union BitInterpreter
  {
   bool              bool_value;       // 布尔值视图：解释位序列为 bool
   char              char_value;       // 有符号字符视图：解释位序列为 char
   uchar             uchar_value;      // 无符号字符视图：解释位序列为 uchar
   short             short_value;      // 短整型视图：解释位序列为 short
   ushort            ushort_value;     // 无符号短整型视图：解释位序列为 ushort
   color             color_value;      // 颜色值视图：解释位序列为 color（本质为 32 位整数）
   int               int_value;        // 整型视图：解释位序列为 int
   uint              uint_value;       // 无符号整型视图：解释位序列为 uint
   datetime          datetime_value;   // 日期时间视图：解释位序列为 datetime（本质为 32 位整数）
   long              long_value;       // 长整型视图：解释位序列为 long
   ulong             ulong_value;      // 无符号长整型视图：解释位序列为 ulong
   float             float_value;      // 单精度浮点视图：解释位序列为 float
   double            double_value;     // 双精度浮点视图：解释位序列为 double
  };

//+------------------------------------------------------------------+
//| 布尔值哈希计算：为 bool 类型生成哈希码                            |
//| 哈希逻辑：true 与 false 对应固定哈希值（通过条件判断区分）          |
//| 返回值：int - 哈希码（true 与 false 对应不同值，确保相等性与哈希一致） |
//| 适用场景：布尔值作为哈希表键（如按“是否启用”分组的配置项）          |
//+------------------------------------------------------------------+
int GetHashCode(const bool value);

//+------------------------------------------------------------------+
//| 有符号字符哈希计算：为 char 类型生成哈希码                         |
//| 哈希逻辑：将 8 位 char 扩展为 32 位 int，通过位运算（| 和 <<）增强哈希分布 |
//| 返回值：int - 哈希码（基于字符的 ASCII 码值计算，确保不同字符哈希大概率不同） |
//| 适用场景：字符作为哈希表键（如按首字母分组的字符串）、字符序列的哈希组合 |
//+------------------------------------------------------------------+
int GetHashCode(const char value);

//+------------------------------------------------------------------+
//| 无符号字符哈希计算：为 uchar 类型生成哈希码                        |
//| 哈希逻辑：与 char 类似，将 8 位 uchar 扩展为 32 位 int，增强哈希分布   |
//| 返回值：int - 哈希码（基于无符号字符值计算，覆盖 0~255 全范围）       |
//| 适用场景：字节数据作为哈希键（如字节流片段、图像像素值）             |
//+------------------------------------------------------------------+
int GetHashCode(const uchar value);

//+------------------------------------------------------------------+
//| 短整型哈希计算：为 short 类型生成哈希码                           |
//| 哈希逻辑：将 16 位 short 转换为 32 位 int，通过位运算合并高低位，增强分布 |
//| 返回值：int - 哈希码（覆盖 short 全范围，确保不同值哈希大概率不同）    |
//| 适用场景：短整型数据作为哈希键（如小范围 ID、16 位计数器）          |
//+------------------------------------------------------------------+
int GetHashCode(const short value);

//+------------------------------------------------------------------+
//| 无符号短整型哈希计算：为 ushort 类型生成哈希码                      |
//| 哈希逻辑：直接将 16 位 ushort 转换为 32 位 int（因范围在 int 可覆盖范围内） |
//| 返回值：int - 哈希码（等于 ushort 本身的值，简单高效）              |
//| 适用场景：无符号短整型数据作为哈希键（如 16 位索引、非负小范围数值）   |
//+------------------------------------------------------------------+
int GetHashCode(const ushort value);

//+------------------------------------------------------------------+
//| 颜色值哈希计算：为 color 类型生成哈希码                           |
//| 哈希逻辑：直接使用 color 的 32 位整数值作为哈希码（color 本质为 ARGB 整数） |
//| 返回值：int - 哈希码（等于颜色的整数表示，确保相同颜色哈希一致）      |
//| 适用场景：颜色作为哈希键（如按颜色分组的图形元素、主题配置）        |
//+------------------------------------------------------------------+
int GetHashCode(const color value);

//+------------------------------------------------------------------+
//| 整型哈希计算：为 int 类型生成哈希码                               |
//| 哈希逻辑：直接返回 int 本身的值（32 位哈希码与值范围一致，无需额外计算） |
//| 返回值：int - 哈希码（等于输入值，高效无损耗）                     |
//| 适用场景：整型数据作为哈希键（如 ID、索引、计数器，最常用的哈希场景之一） |
//+------------------------------------------------------------------+
int GetHashCode(const int value);

//+------------------------------------------------------------------+
//| 无符号整型哈希计算：为 uint 类型生成哈希码                          |
//| 哈希逻辑：将 32 位 uint 转换为 int（截断高位，因哈希码为 32 位有符号整数） |
//| 返回值：int - 哈希码（uint 的 32 位值直接映射为 int，可能为负数但不影响哈希分布） |
//| 适用场景：无符号整型数据作为哈希键（如 32 位唯一标识、哈希值中间结果） |
//+------------------------------------------------------------------+
int GetHashCode(const uint value);

//+------------------------------------------------------------------+
//| 日期时间哈希计算：为 datetime 类型生成哈希码                        |
//| 哈希逻辑：将 datetime 转换为 long 后，通过异或（^）合并高低 32 位，压缩为 32 位哈希 |
//| 返回值：int - 哈希码（基于时间戳的完整信息计算，确保不同时间哈希大概率不同） |
//| 适用场景：时间作为哈希键（如按时间分组的日志、定时任务缓存）        |
//+------------------------------------------------------------------+
int GetHashCode(const datetime value);

//+------------------------------------------------------------------+
//| 长整型哈希计算：为 long 类型生成哈希码                            |
//| 哈希逻辑：将 64 位 long 的高低 32 位异或（^），压缩为 32 位哈希码，保留关键位信息 |
//| 返回值：int - 哈希码（合并长整型的高低位特征，平衡哈希分布与信息保留） |
//| 适用场景：长整型数据作为哈希键（如 64 位 ID、高精度时间戳）          |
//+------------------------------------------------------------------+
int GetHashCode(const long value);

//+------------------------------------------------------------------+
//| 无符号长整型哈希计算：为 ulong 类型生成哈希码                       |
//| 哈希逻辑：与 long 类似，将 64 位 ulong 的高低 32 位异或（^），压缩为 32 位哈希 |
//| 返回值：int - 哈希码（合并无符号长整型的高低位特征，适应大范围数值）   |
//| 适用场景：无符号长整型数据作为哈希键（如 64 位哈希值、超大范围计数器） |
//+------------------------------------------------------------------+
int GetHashCode(const ulong value);

//+------------------------------------------------------------------+
//| 单精度浮点哈希计算：为 float 类型生成哈希码                         |
//| 哈希逻辑：                                                        |
//|  1. 特殊处理：0 与 -0 视为相等，返回相同哈希码（0）；               |
//|  2. 常规处理：通过 BitInterpreter 将 float 的位模式转换为 int，以位序列作为哈希依据； |
//| 返回值：int - 哈希码（基于浮点值的二进制表示，确保相等浮点值哈希一致） |
//| 注意事项：浮点精度问题可能导致“数值接近但不等”的两个 float 哈希不同，符合设计预期 |
//| 适用场景：单精度浮点数据作为哈希键（如低精度传感器数据、图形坐标）    |
//+------------------------------------------------------------------+
int GetHashCode(const float value);

//+------------------------------------------------------------------+
//| 双精度浮点哈希计算：为 double 类型生成哈希码                        |
//| 哈希逻辑：                                                        |
//|  1. 特殊处理：0 与 -0 视为相等，返回相同哈希码（0）；               |
//|  2. 常规处理：通过 BitInterpreter 将 double 的位模式转换为 long，再异或高低 32 位生成哈希； |
//| 返回值：int - 哈希码（基于双精度浮点的二进制表示，平衡精度与哈希分布） |
//| 注意事项：同 float，哈希不同不代表数值差异大，仅反映位模式不同         |
//| 适用场景：双精度浮点数据作为哈希键（如金融价格、高精度测量数据）      |
//+------------------------------------------------------------------+
int GetHashCode(const double value);

//+------------------------------------------------------------------+
//| 字符串哈希计算：为 string 类型生成哈希码                           |
//| 哈希逻辑（经典多项式哈希）：                                       |
//|  hash = s[0] * 31^(n-1) + s[1] * 31^(n-2) + ... + s[n-1]           |
//|  其中 s[i] 为字符串第 i 个字符的 Unicode 码值，n 为字符串长度，31 为质数基底（减少哈希碰撞） |
//| 返回值：int - 哈希码（基于字符序列计算，空字符串返回 0，相同字符序列哈希一致） |
//| 优势：对字符顺序敏感（"abc" 与 "cba" 哈希不同），分布均匀，碰撞率低   |
//| 适用场景：字符串作为哈希键（如字典键、名称索引、路径缓存）          |
//+------------------------------------------------------------------+
int GetHashCode(const string value);

//+------------------------------------------------------------------+
//| 泛型哈希计算：为自定义类型生成哈希码                               |
//| 哈希逻辑（优先级）：                                              |
//|  1. 若自定义类型实现 IEqualityComparable<T> 接口：调用其 HashCode() 方法（使用自定义哈希逻辑）； |
//|  2. 否则：使用类型名称（typename(value)）的哈希码作为默认值（不推荐，可能导致高碰撞率）； |
//| 返回值：int - 哈希码（自定义逻辑优先，确保与 Equals 逻辑匹配）       |
//| 使用要求：自定义类型应实现 IEqualityComparable<T> 接口并重写 HashCode()，否则哈希质量差 |
//| 示例：                                                           |
//|  class COrder : public IEqualityComparable<COrder> {              |
//|      int m_id; double m_price;                                   |
//|      int HashCode() override {                                   |
//|          return ::GetHashCode(m_id) ^ ::GetHashCode(m_price); // 组合字段哈希 |
//|      }                                                           |
//|  };                                                              |
//+------------------------------------------------------------------+
template<typename T>
int GetHashCode(T value);
//+------------------------------------------------------------------+